function hfile = vtc_Filter(hfile, opts)
% VTC::Filter  - filter a VTC
%
% FORMAT:       [vtc =] vtc.Filter(opts)
%
% Input fields:
%
%       opts        mandatory struct but with optional fields
%        .spat      enable spatial filtering (default: false)
%        .spkern    smoothing kernel in mm (default: [6, 6, 6])
%        .temp      enable temporal filtering (default: false)
%        .tempdct   DCT-based filtering (min. wavelength, default: Inf)
%        .tempdt    detrend (default: true, is overriden by dct/sc)
%        .templp    temporal lowpass (smoothing) kernel in secs (def: 0)
%        .tempsc    sin/cos set of frequencies (number of pairs, def: 0)
%
% Output fields:
%
%       vtc         filtered VTC

% Version:  v0.7g
% Build:    9031016
% Date:     Mar-10 2009, 4:33 PM CET
% Author:   Jochen Weber, SCAN Unit, Columbia University, NYC, NY, USA
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

% argument check
if nargin < 2 || ...
    numel(hfile) ~= 1 || ...
   ~isBVQXfile(hfile, 'vtc') || ...
   ~isstruct(opts) || ...
    numel(opts) ~= 1 || ...
   (~isfield(opts, 'spat') && ...
    ~isfield(opts, 'temp'))
    error( ...
        'BVQXfile:BadArgument', ...
        'Invalid call to %s.', ...
        mfilename ...
    );
end
bc = bvqxfile_getcont(hfile.L);
if ~isfield(opts, 'spat') || ...
   (~islogical(opts.spat) && ...
    ~isnumeric(opts.spat)) || ...
    numel(opts.spat) ~= 1
    opts.spat = false;
else
    opts.spat = (opts.spat ~= 0);
end
if ~isfield(opts, 'temp') || ...
   (~islogical(opts.temp) && ...
    ~isnumeric(opts.temp)) || ...
    numel(opts.temp) ~= 1
    opts.temp = false;
else
    opts.temp = (opts.temp ~= 0);
end
if ~isfield(opts, 'spkern') || ...
   ~isa(opts.spkern, 'double') || ...
    numel(opts.spkern) ~= 3 || ...
    any(isinf(opts.spkern) | isnan(opts.spkern) | opts.spkern < 0 | opts.spkern > 20)
    opts.spkern = [6, 6, 6];
else
    opts.spkern = opts.spkern(:)';
end
opts.spkern = opts.spkern ./ bc.Resolution;
if all(opts.spkern < 0.5)
    opts.spat = false;
end
if opts.temp
    if ~isfield(opts, 'tempdct') || ...
       ~isa(opts.tempdct, 'double') || ...
        numel(opts.tempdct) ~= 1 || ...
        isinf(opts.tempdct) || ...
        isnan(opts.tempdct) || ...
        opts.tempdct < 30
        opts.tempdct = Inf;
    else
        opts.tempdct = opts.tempdct ./ (0.001 * bc.TR);
    end
    if ~isfield(opts, 'tempdt') || ...
       ~islogical(opts.tempdt) || ...
        numel(opts.tempdt) ~= 1
        opts.tempdt = true;
    end
    if ~isfield(opts, 'templp') || ...
       ~isa(opts.templp, 'double') || ...
        numel(opts.templp) ~= 1 || ...
        isinf(opts.templp) || ...
        isnan(opts.templp) || ...
        opts.templp < 0 || ...
        opts.templp > 20
        opts.templp = 0;
    else
        opts.templp = opts.templp ./ (0.001 * bc.TR);
    end
    if ~isfield(opts, 'tempsc') || ...
       ~isa(opts.tempsc, 'double') || ...
        numel(opts.tempsc) ~= 1 || ...
       ~any(opts.tempsc == (1:12))
        opts.tempsc = 0;
    end
    if isinf(opts.tempdct) && ...
       ~opts.tempdt && ...
        opts.templp == 0 && ...
        opts.tempsc == 0
        opts.temp = false;
    elseif opts.tempsc > 0
        opts.tempdct = Inf;
        opts.tempdt = false;
    end
end
if ~opts.spat && ...
   ~opts.temp
    return;
end

% patch opts
opts.tdim = 1;

% and do work
bc.VTCData = tempfilter(bc.VTCData, opts);

% but content into array
bvqxfile_setcont(hfile.L, bc);
